import math
from pydoc import text
import pyautogui
import time
import random
import os
import datetime
import json
import json
import os
import sys
import threading
import queue
import pyperclip
import win32gui
import win32process
import psutil
import subprocess
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, 
                            QTextEdit, QVBoxLayout, QWidget)
from PyQt5.QtCore import Qt, QTimer, QObject, pyqtSignal
from app.interface_walmart.MySQLHelper_walmart import MySQLHelper
import uuid
import random
from datetime import datetime
import traceback
import requests
import base64
import math
import time
import pygetwindow as gw
import win32con
from baidu_location import baidu_location
from follow_baidu_last import get_baidu3_location_json
class MessageSender(QObject):
    textUpdateSignal = pyqtSignal(str)
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        # self.start_btn.click()
        self.show()
        self.sender = MessageSender()
        self.sender.textUpdateSignal.connect(self.text_memo.append)
        self.setGeometry(970, 340, 300, 1000)

        # print(ziniaoaccount)
        self.seqs=[]
        self.seqindex=0
        # self.ziniao_walmart_follow(5,'change')
        self.text_memo.append('2个任务不可以同时在一台电脑执行...\n')

    def init_ui(self):
        self.setWindowTitle('RPA跟卖')
        # self.start_btn = QPushButton('开始跟卖任务', self)
        # self.start_btn.clicked.connect(self.start_task)

        # self.change_btn = QPushButton('开始改价任务', self)
        # self.change_btn.clicked.connect(self.change_task)
        self.start_btn = QPushButton('开始跟卖任务', self)
        self.start_btn.clicked.connect(self.start_task_thread)
        self.start_btn.setStyleSheet("""
        QPushButton {
            background-color: #4CAF50;  /* Green */
            color: white;
            border: none;
            padding: 5px;
        }
        QPushButton:disabled {
            background-color: #808080;  /* Gray */
            color: #696969;
        }
    """)

        self.change_btn = QPushButton('开始改价任务', self)
        self.change_btn.clicked.connect(self.change_task_thread)
        self.change_btn.setStyleSheet("""
        QPushButton {
            background-color: #00008B;  /* Dark blue */
            color: white;
            border: none;
            padding: 5px;
        }
        QPushButton:disabled {
            background-color: #808080;  /* Gray */
            color: #696969;
        }
    """)

        self.text_memo = QTextEdit(self)
        self.text_memo.setReadOnly(True)
        layout = QVBoxLayout()
        layout.addWidget(self.start_btn)
        layout.addWidget(self.change_btn)
        layout.addWidget(self.text_memo)
        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)
        self.dbhelper=MySQLHelper()
        # self.close_windows_by_processname('ziniao.exe')

    def start_task_thread(self):
        self.thread1=threading.Thread(target=self.start_task)
        self.thread1.start()
    def start_task(self):
        """启动任务线程"""
        self.start_btn.setEnabled(False)
        self.start_btn.setStyleSheet("background-color: gray; color: darkgray;")  # 新增禁用状态样式

        current_dir = os.getcwd()
        json_file_path = os.path.join(current_dir, 'app', 'interface', 'rpa_login.json')
        self.start_btn.setEnabled(False)
        sql='select * from app_zbirdaccount where is_active=1'
        ziniaoaccount=self.dbhelper.query(sql)
        for row in ziniaoaccount:
            self.ziniao_login(row['id'],row['loginname'],row['password'],followtype='follow')
        
    def change_task_thread(self):
        self.thread2=threading.Thread(target=self.change_task)
        self.thread2.start()
    def change_task(self):
        """启动任务线程"""
        self.change_btn.setEnabled(False)
        self.change_btn.setStyleSheet("background-color: gray; color: darkgray;")  # 新增禁用状态样式

        current_dir = os.getcwd()
        json_file_path = os.path.join(current_dir, 'app', 'interface', 'rpa_login.json')
        self.change_btn.setEnabled(False)
        sql='select * from app_zbirdaccount where is_active=1'
        ziniaoaccount=self.dbhelper.query(sql)
        for row in ziniaoaccount:
            self.ziniao_login(row['id'],row['loginname'],row['password'],followtype='change')
    def ziniao_login(self,zbird_account_id,ziniaoaccount,ziniaopassword,followtype='follow'):
        # self.check_country_origin_in_active_window()
 
        current_dir = os.getcwd()
        image_dirpath = os.path.join(current_dir, 'app', 'interface','png')
        # locaopen=pyautogui.locateOnScreen(image_path)
        # if locaopen:    
        #     print(locaopen)
        #     time.sleep(2.5)
        self.text_memo.append("开始执行任务...\n")
        self.text_memo.append("正在启动紫鸟客户端...\n")
        pyautogui.FAILSAFE = True
        pyautogui.PAUSE = 1
        orderindex=0
        addtionalheight=(orderindex -1)*88
        # 进行登录操作
        sql=f'select * from app_walmartaccount  where zbird_account_id={zbird_account_id}'
        walmartaccount=self.dbhelper.query(sql)
        if len(walmartaccount)==0:
            return
        subprocess.Popen(r"F:\Program Files\ziniao\ziniao.exe")
        time.sleep(0.5*random.random())
        self.set_window_position('ziniao.exe',1350,5,480,1000)
        while self.is_ziniaobrowser_window_exist('ziniao.exe')==False:
            time.sleep(0.5*random.random())
            self.sender.textUpdateSignal.emit('没有找到紫鸟窗口')

        # window_rect = list(self.get_window_info('ziniao.exe'))
        window_rect=[]
        window_rect.append(1350) 
        window_rect.append(5)
        window_rect.append(480)
        window_rect.append(1000)
        images=['triangel.png','logout.png','eplogin.png','epname.png','epinputpassword.png']
        images=['logout.png','eplogin.png']
        pyautogui.doubleClick(random.randint(1400,1500),random.randint(25,30))
        for index,image in enumerate(images,start=1):
            image1=os.path.join(image_dirpath,image)
            center=self.get_location_by_image(image1,window_rect)
            if center:
                self.sender.textUpdateSignal.emit(f"成功点击{image.replace('.png','')}")
                pyautogui.doubleClick(center[0],center[1])
                time.sleep(0.1*random.random())
            else:
                self.sender.textUpdateSignal.emit(f"没有找到，没有点击{image.replace('.png','')}")

        time.sleep(0.5*random.random())


        print('设置窗口位置')
        # pyautogui.click(1518,370)
        # 第三步张林余002
        time.sleep(6.5)
        # 输入登录账号
        x,y=window_rect[0]+random.randint(238,242), window_rect[1]+random.randint(475,480)
        print(x,y)
        pyautogui.click(x,y)
        # 登录账号输入位置，是顶部Y坐标增加477。
        # 密码输入位置，是顶部Y坐标增加542。
        # X坐标增加160张林余002
        pyautogui.press('backspace', presses=20)
        pyautogui.press('delete', presses=20)
        time.sleep(0.5)
        pyperclip.copy(ziniaoaccount)
        pyautogui.hotkey('ctrl', 'v') 
        self.sender.textUpdateSignal.emit(f'输入登录账号{ziniaoaccount}')

        # 第四步
        self.sender.textUpdateSignal.emit('输入登录密码')
        pyautogui.click(window_rect[0]+random.randint(238,242), window_rect[1]+random.randint(540,544))
        pyautogui.press('backspace', presses=20)
        pyautogui.press('delete', presses=20)

        time.sleep(0.5)
        pyautogui.write( ziniaopassword,interval=0.1)
        self.text_memo.append('输入密码后，按下回车')
        pyautogui.press('enter', presses=2)
        dirpath=os.path.join(os.getcwd(),'screenshot')
        os.makedirs(dirpath,exist_ok=True)
        # 直接登录了，直接登录了。进入紫鸟ziniaobrowser.exe界面
        time.sleep(5.5)
        print(f'当前沃尔玛账号数量:{len(walmartaccount)}')
        for row2 in walmartaccount:
            self.sender.textUpdateSignal.emit(f'开始{followtype},{row2["tag"]}')
            self.ziniao_walmart_follow(row2['id'],followtype)
            self.sender.textUpdateSignal.emit(f'结束{followtype},{row2["tag"]}')
        self.sender.textUpdateSignal.emit(f'全部结束{followtype}')

    
    def is_ziniaobrowser_window_exist(self,exename='ziniaobrowser.exe'):
        """检查是否存在ziniaobrowser.exe进程的窗口"""
        window_found = False
        
        def callback(hwnd, _):
            nonlocal window_found
            try:
                _, pid = win32process.GetWindowThreadProcessId(hwnd)
                process = psutil.Process(pid)
                if exename in process.name().lower():
                    window_found = True
            except (psutil.NoSuchProcess, psutil.AccessDenied, PermissionError):
                return
            except Exception as e:
                print(f"窗口检查异常: {str(e)}")
                return
    
        win32gui.EnumWindows(callback, None)
        return window_found        
    def ziniao_walmart_follow(self,walmartaccountid,followtype='follow'):
        self.set_window_position('ziniao.exe',1350,5,480,1000)
        current_dir = os.getcwd()
        image_dirpath = os.path.join(current_dir, 'app', 'interface','png')
        sqlwalmartaccount=f'select * from app_walmartaccount  where id={walmartaccountid}'
        row_walmart_account=self.dbhelper.query(sqlwalmartaccount)
        sql2=f'select * from app_skus_new  where   newsku is null and price is not null and lastfollow_date is   null   and (upc is not null and   LENGTH(upc) > 6 ) and walmart_account_id={walmartaccountid}'
        if followtype=='change':
            sql2=f'select * from app_skus_new  where   newsku is not null and  abs(price+ifnull(deliveryfee,0)-price2-ifnull(olddeliveryfee,0)) <0.01 and (TIMESTAMPDIFF(MINUTE, lastchangeprice_date, NOW()) >= 720 or lastchangeprice_date is null) and walmart_account_id={walmartaccountid}'

        print(sql2)
        data_app_skus=self.dbhelper.query(sql2)
        print(f'当前跟卖sku数量:{len(data_app_skus)}')
        if len(data_app_skus)>0:
            orderindex=row_walmart_account[0]['orderindex']
            # orderindex=2
            addtionalheight=(orderindex -1)*88
            # 打开一个沃尔玛新账号前，关闭窗口；
            self.close_windows_by_processname('ziniaobrowser.exe')
            # 第六步，等待出现新页面，在这里，选择账号，需要按照每个沃尔玛账号的顺序，进行点击
            self.human_like_move_and_click(1750, 246 + addtionalheight)
            time.sleep(5.5)
            self.set_window_position('ziniaobrowser.exe',1,1)
            time.sleep(0.5)
            # pyautogui.hotkey('ctrl', 'tab') #第一次点击紫鸟浏览器后，关闭多余的页签
            while  self.is_ziniaobrowser_window_exist()==False:
                time.sleep(random.random()*3)
            self.set_window_position('ziniaobrowser.exe',1,0,1016,1006)
            center=self.get_location_by_image(os.path.join(image_dirpath,'noaccount.png'))
            if center:
                self.human_like_move_and_click(center[0],center[1])
                pyautogui.hotkey('ctrl', 'w') 
            images=['visitmany.png','openaccount.png','login.png','catalog.png']   
            if followtype=='follow':
               images.append('addtiems1.png')
            for index,image in enumerate(images,start=1):
                image_path=os.path.join(image_dirpath,image)
                center=self.get_location_by_image(image_path)
                # if index==4:
                #     pyautogui.hotkey('ctrl', '2')  # 切换到第二个标签页（大多数浏览器支持）
                #     pyautogui.hotkey('ctrl', 'l')  # 聚焦地址栏
                #     pyautogui.write('https://seller.walmart.com/catalog/list-items')
                #     pyautogui.press('enter')
                # else:
                trytimes=0
                while center is None or center ==False:  
                    time.sleep(0.5)
                    center=self.get_location_by_image(image_path)
                    print(f'没有找到{image}')
                    trytimes+=1
                    if trytimes>5:
                        pyautogui.hotkey('ctrl', 'w') 
                        window_rect2=[]
                        window_rect2.append(350) 
                        window_rect2.append(5)
                        window_rect2.append(550)
                        window_rect2.append(40)
                        closewindowpngpath=os.path.join(image_dirpath,'closewindow.png')
                        center=self.get_location_by_image(closewindowpngpath,window_rect2)
                        if center:
                            self.human_like_move_and_click(center[0],center[1])
                            self.sender.textUpdateSignal.emit(f'成功点击closewindow按钮')
                            time.sleep(random.random()*3)
                if center:
                        self.human_like_move_and_click(center[0],center[1])
                        self.sender.textUpdateSignal.emit(f'成功点击{image.replace(".png","")}按钮')
                        time.sleep(random.random()*3)
                else:
                    print(f'没有点击{image.replace(".png","")}')
                    self.sender.textUpdateSignal.emit(f'没有点击{image.replace(".png","")}')
            match(followtype):
                case 'follow':
                    self.ziniao_follow(row_walmart_account ,data_app_skus)  
                case 'change':
                    self.ziniao_change(row_walmart_account ,data_app_skus)   
   
            
                    
    def ziniao_follow(self,row_walmart_account,data_app_skus):  
        image_dirpath=os.path.join(os.getcwd(),'app','interface','png')
        addtionprice=-0.1
        username=row_walmart_account[0]['username']
        now = datetime.now()
        self.set_window_position('ziniaobrowser.exe',1,0,1016,1006)
        code_part =random.choice("ABCDEF")                  # 固定代号
        year_part = str(now.year)[-1]      # 年份最后一位
        month_part = f"{now.month:02d}"    # 两位数月份
        prefix_part =random.choice("GHIJKLM")                # 固定前缀
        for index,row in enumerate(data_app_skus,start=1) :
            try:
                print(row['sku'])

                sku=row['sku']
                price=row['price']
                new_sku_code=self.get_sequence()
                print(new_sku_code)
                timestamp = str(int(time.time() ))
                tax_numeric_id=timestamp
                if index==1:
                    images=['gtinupcfind.png','additem2.png','newsku.png','sellingprice.png','measure.png','unitselect.png','tax.png','country.png','submit.png','itemsuccessfullysubmitted.png']
                else:
                    images=['rewriteupc.png','additem2.png','newsku.png','sellingprice.png','measure.png','unitselect.png','tax.png','country.png','submit.png','itemsuccessfullysubmitted.png']
                gooncontinueprocess=1
                for index_image,image in enumerate(images,start=1):
                    imagex=os.path.join(image_dirpath,image)
                    image_path=os.path.join(image_dirpath,image)
                    imagename=image.replace('.png','').lower()
                    print(imagename)
                        
                    center=self.get_location_by_image(image_path)
                    if center:
                        print(center)
                        self.sender.textUpdateSignal.emit(f'成功点击{sku},{index}/{len(data_app_skus)},{index_image},{imagename}')
                    else:
                        self.sender.textUpdateSignal.emit(f'没有点击{sku},{index}/{len(data_app_skus)},{index_image},{imagename}')
                    addtionalitemheight=0
                    if gooncontinueprocess==0:
                        break
                    if center:
                        match(imagename):

                            case 'newsku'| 'sellingprice' |   'country' | 'tax':  
                                addtionalitemheight=30  
                                self.human_like_move_and_click(center[0]+random.randint(50,70),center[1]+ addtionalitemheight + int(30 * random.random() ))
                            case 'rewriteupc':
                                self.human_like_move_and_click(center[0] - random.randint(50,70),center[1]  )
                                time.sleep(0.1*random.random())

                                # 
                                pyautogui.press('backspace',15)
                                time.sleep(0.1*random.random())
                                pyautogui.press('delete')  
                                time.sleep(0.1*random.random())
                                pyautogui.press('backspace', presses=15)  # 按20次退格键
                                pyautogui.write(row['upc'], interval=0.1)
                                pyautogui.press('enter',presses=2)  

                                
                                time.sleep(2+random.random()*2)
                                image_edititem=os.path.join(image_dirpath,'edititem.png')
                                center2=self.get_location_by_image(image_edititem)
                                keyaction=''
                                if center2:
                                    upc2=row['upc']
                                    keyaction=f'产品已经跟卖过:upc->{upc2}'
                                    sql=f'update app_skus_new set lastfollow_date=now() where id={row["id"]}'
                                    self.dbhelper.execute(sql)
                                
                                image_edititem=os.path.join(image_dirpath,'cannnotfindtheitem.png')
                                center2=self.get_location_by_image(image_edititem)
                                if center2:
                                    keyaction=f'产品不存在:upc->{upc2}，无法跟卖'
                                if keyaction:
                                    self.text_memo.append(keyaction)
                                    sql=f'insert into sku_keywords_history (sku,opdate,username,keywords) values ("{sku}",now(),"{username}","{keyaction}")'
                                    print(sql)
                                    self.dbhelper.execute(sql)
                                    gooncontinueprocess=0
                                    break
                                # 检查是否跟卖过了，或者产品不存在，则关闭；并且写日志；

                            case _:
                                self.human_like_move_and_click(center[0]+random.randint(45,46),center[1]+ random.randint(1,2) )
                        time.sleep(2+ random.random()*2)
                        match(imagename):
                            case 'gtinupcfind':
                                pyautogui.press('backspace', presses=20)  # 按20次退格键
                                pyautogui.write(row['upc'], interval=0.1)
                                pyautogui.press('enter',presses=2)  

                                time.sleep(random.random()*2)
                                # pyautogui.hotkey('ctrl', 'a') 
                                # 删除选中内容
                                
                                time.sleep(2+random.random()*2)
                                image_edititem=os.path.join(image_dirpath,'edititem.png')
                                center2=self.get_location_by_image(image_edititem)
                                keyaction=''
                                if center2:
                                    upc2=row['upc']
                                    keyaction=f'产品已经跟卖过:upc->{upc2}'
                                    sql=f'update app_skus_new set lastfollow_date=now() where id={row["id"]}'
                                    self.dbhelper.execute(sql)
                                
                                image_edititem=os.path.join(image_dirpath,'cannnotfindtheitem.png')
                                center2=self.get_location_by_image(image_edititem)
                                if center2:
                                    keyaction=f'产品不存在:upc->{upc2}，无法跟卖'
                                    

                                if keyaction:
                                    self.text_memo.append(keyaction)
                                    sql=f'insert into sku_keywords_history (sku,opdate,username,keywords) values ("{sku}",now(),"{username}","{keyaction}")'
                                    print(sql)
                                    self.dbhelper.execute(sql)
                                    gooncontinueprocess=0
                                    break
                                # 检查是否跟卖过了，或者产品不存在，则关闭；并且写日志；

                            case 'newsku':
                                pyautogui.press('backspace', presses=20)  # 按20次退格键
                                pyautogui.write(new_sku_code, interval=0.1)
                                pyautogui.press('enter',presses=2)     
                            case 'sellingprice':
                                deliveryfee=row['deliveryfee'] if row['deliveryfee'] else 0
                                pyautogui.write(str(float(price)+float(addtionprice)+float(deliveryfee)), interval=0.1)
                                pyautogui.press('enter',presses=2)     
                            case 'measure':
                                pyautogui.write('1', interval=0.1)
                                pyautogui.press('enter',presses=2)   
                                
        
        
                            case 'unitselect':
                                self.human_like_move_and_click(center[0] - random.randint(10,20), center[1] + random.randint(58,62))
                                time.sleep(random.random()*0.3)
                                    
                            case 'country':
                                cx,cy=center[0] + random.randint(350,410), center[1] - random.randint(400,450)
                                self.human_like_move_and_click(cx,cy)
                                self.human_like_move_and_click(cx,cy)
                                intcontinue=1
                                for ix in range(40):
                                    if intcontinue==0:
                                        continue
                                    pyautogui.scroll(-120)
                                    time.sleep(0.2*random.random())
                                    if ix >6:
                                        centerc=self.get_location_by_image(os.path.join(image_dirpath,'china.png'))
                                        if centerc:
                                            self.human_like_move_and_click(centerc[0] , centerc[1]  ) 
                                            intcontinue=0
                            case 'tax':
                                pyautogui.write(tax_numeric_id, interval=0.1)
                                time.sleep(random.random()*0.3)
                                # pyautogui.press('enter',presses=2) 
                            case "submit":
                                for ix in range(6):
                                    pyautogui.scroll(-240)
                                    time.sleep(0.2*random.random()) 
                            case 'itemsuccessfullysubmitted':
                                pyautogui.hotkey('ctrl', 'w') 
                                sql=f'insert into sku_keywords_history (sku,opdate,fromprice,toprice,username) values ("{sku}",now(),0,{price},"{username}")'
                                print(sql)
                                self.dbhelper.execute(sql)
                                sql=f'update app_skus_new set newsku="{new_sku_code}",newprice={float(price)+float(addtionprice)},lastfollow_date=now() where id={row["id"]}'
                                print(sql)
                                self.dbhelper.execute(sql)
                    # 移动鼠标到指定位置                   
                    # 适用于大多数浏览器
                    time.sleep(0.2)
            except Exception as e:
                print(f'跟卖失败{sku}->{new_sku_code}->{price}')
                traceback.print_exc()   
                self.sender.textUpdateSignal.emit(f'跟卖失败{traceback.format_exc()}')
        print('处理完毕')    
    def ziniao_change(self,row_walmart_account,data_app_skus):  
        image_dirpath=os.path.join(os.getcwd(),'app','interface','changepng')
        addtionprice=-0.1
        username=row_walmart_account[0]['username']
        now = datetime.now()
        self.set_window_position('ziniaobrowser.exe',1,0,1280,1015)
        for index,row in enumerate(data_app_skus,start=1) :
            try:
                print(row['newsku'])
                # pyautogui.scroll(200)
                sku=row['newsku']
                oldprice=row['price2']
                newprice=row['price']
                new_sku_code=self.get_sequence()
                if index==1:
                    images=['searchbysku.png','price_ca_1.png','price_toclick.png']
                else:
                    images=['searchbysku_2.png','price_ca_1.png','price_toclick.png']
                gooncontinueprocess=1
                for index_image,image in enumerate(images,start=1):
                    imagex=os.path.join(image_dirpath,image)
                    image_path=os.path.join(image_dirpath,image)
                    imagename=image.replace('.png','').lower()
                    print(imagename)
                    center=self.get_location_by_image(image_path)
                    if center:
                        print(center)
                        self.sender.textUpdateSignal.emit(f'成功点击{sku},{index}/{len(data_app_skus)},{index_image},{imagename}')
                    else:
                        self.sender.textUpdateSignal.emit(f'没有点击{sku},{index}/{len(data_app_skus)},{index_image},{imagename}')
                    addtionalitemheight=0
                    if center:
                        match(imagename):
                            case 'price_ca_1':  
                                addtionalitemheight=62  
                                self.human_like_move_and_click(center[0]+random.randint(1,3),center[1]+ random.randint(58,67) )
                                time.sleep(2+ random.random()*2)
                            case 'searchbysku_2': 
                                self.human_like_move_and_click(center[0]- random.randint(30,50),center[1] )   
                                pyautogui.press('backspace',random.randint(15,20))
                                time.sleep(0.1*random.random())
                                pyautogui.press('delete',random.randint(15,20))  
                                time.sleep(0.1*random.random())
                                pyautogui.write(str(row['newsku']), interval=0.1)
                                pyautogui.press('enter',presses=random.randint(1,2))  
                                
                                time.sleep(2+ random.random()*2)
                                image_edititem=os.path.join(image_dirpath,'noskufoundtochangeprice.png')
                                center2=self.get_location_by_image(image_edititem)
                                if center2:
                                    keyaction=f'产品不存在:sku->{sku}，无法跟价改价'
                                    self.text_memo.append(keyaction)
                                    sql=f'insert into sku_keywords_history (sku,opdate,username,keywords) values ("{sku}",now(),"{username}","{keyaction}")'
                                    print(sql)
                                    self.dbhelper.execute(sql)
                                    break
                            case 'searchbysku':
                                self.human_like_move_and_click(center[0] + random.randint(50,70),center[1]  )
                                pyautogui.write(row['newsku'], interval=0.1)
                                pyautogui.press('enter',presses=random.randint(1,2))  
                                time.sleep(2+ random.random()*2)
                                # 再确定是否找到了sku，如果没有找到，则写日志，并退出；
                                image_edititem=os.path.join(image_dirpath,'noskufoundtochangeprice.png')
                                center2=self.get_location_by_image(image_edititem)
                                if center2:
                                    keyaction=f'产品不存在:sku->{sku}，无法跟价改价'
                                    self.text_memo.append(keyaction)
                                    sql=f'insert into sku_keywords_history (sku,opdate,username,keywords) values ("{sku}",now(),"{username}","{keyaction}")'
                                    print(sql)
                                    self.dbhelper.execute(sql)
                                    break
                                    
                                     
                            case 'price_toclick':
                                self.human_like_move_and_click(center[0] + random.randint(50,70),center[1]  )
                                pyautogui.press('backspace',random.randint(7,8))
                                time.sleep(0.1*random.random())
                                pyautogui.press('delete',random.randint(7,8))  
                                time.sleep(0.1*random.random())
                                print('最新价格',row['price'])
                                deliveryfee=row['deliveryfee'] if row['deliveryfee'] else 0
                                pyautogui.write(str(float(row['price'])-0.1+float(deliveryfee)), interval=0.1) 
                                print('跟卖价格',str(float(row['price'])-0.1+float(deliveryfee)))
                                pyautogui.press('enter',presses=2) 
                                time.sleep(1+ random.random()*2)
                                for ix1 in range(2):
                                    pyautogui.press('tab',presses=1) 
                                    time.sleep(0.1*random.random())
                                pyautogui.press('enter',presses=2) 
                                self.text_memo.append(f'{sku}->{row["price"]}->{row["price2"]}')
                                sql=f'insert into sku_keywords_history (sku,opdate,username,keywords) values ("{sku}",now(),"{username}","修改价格从{oldprice}到{newprice}")'
                                print(sql)
                                self.dbhelper.execute(sql)
                                sql=f'update app_skus_new set price2={newprice},lastchangeprice_date=now() where id={row["id"]}'
                                print(sql)
                                self.dbhelper.execute(sql)
                            case 'updateprice':
                                self.human_like_move_and_click(center[0]  ,center[1]  )
                                
                        time.sleep(0.2)
            except Exception as e:
                self.sender.textUpdateSignal.emit(f'跟价改价失败{traceback.format_exc()}')
                traceback.print_exc()   
        print('处理完毕')    
    def get_location_by_image(self,image_path,window_rect=(1, 0, 1280, 1115)):
        try:
            
            if os.path.exists(image_path):
                 # 格式：(left, top, width, height)
                locaopen = pyautogui.locateOnScreen(
                    image_path,
                    confidence=0.7,
                    minSearchTime=3,
                    region=window_rect  #
                )
                if locaopen:
                    center = pyautogui.center(locaopen)
                    # 点击图像中心
                    return center
                else:
                    return None
            else:
                return None
        except Exception as e:
            print(f'出现异常{image_path}->{e}')
            # traceback.print_exc()
            return None
    
    def human_like_move_and_click(self,dest_x, dest_y, duration=0.4, click=True):
        try:
            # 获取初始位置
            start_x, start_y = pyautogui.position()
            # 计算移动路径参数
            distance = math.hypot(dest_x - start_x, dest_y - start_y)
            steps = max(int(distance / 150), 8)  # 至少10步
            step_time = duration / steps
            # 生成带扰动的移动路径
            for i in range(steps):
                # 使用缓动函数（easeOutQuad）
                t = (i + 1) / steps
                progress = 1 - (1 - t) ** 2
                current_x = start_x + (dest_x - start_x) * progress
                current_y = start_y + (dest_y - start_y) * progress
                # 添加随机扰动（不超过5像素）
                current_x += random.uniform(-3, 3)
                current_y += random.uniform(-3, 3)
                # 确保坐标在屏幕范围内
                current_x = max(0, min(pyautogui.size().width-100, current_x))
                current_y = max(0, min(pyautogui.size().height-100, current_y))
                pyautogui.moveTo(current_x, current_y, duration=step_time)
                # 添加随机延迟（最后几步更慢）
                if i > steps - 3:
                    time.sleep(random.uniform(0.02, 0.05))

            # 最终精确移动
            final_x = dest_x + random.randint(-2, 2)
            final_y = dest_y + random.randint(-2, 2)
            pyautogui.moveTo(final_x, final_y, duration=0.1)

            pyautogui.moveTo(final_x, final_y, duration=random.uniform(0.05, 0.15))
        
            if click:
                # 增加点击前犹豫（50%概率）
                if random.random() < 0.5:
                    time.sleep(random.uniform(0.1, 0.3))
                    
                # 模拟更真实的点击动作
                pyautogui.mouseDown()
                time.sleep(random.uniform(0.1, 0.3))  # 延长按压时间
                pyautogui.mouseUp()
                
                # 点击后停留（增加随机性）
                stay_duration = random.uniform(0.8, 2.5)  # 延长停留时间范围
                if stay_duration > 1.5:
                    # 添加微小移动模拟手指颤抖
                    for _ in range(2):
                        pyautogui.moveRel(
                            random.randint(-3, 3),
                            random.randint(-3, 3),
                            duration=0.05
                        )
                        time.sleep(0.05)
                time.sleep(stay_duration)
                
                # 50%概率在离开前轻微移动
                if random.random() < 0.5:
                    pyautogui.moveRel(
                        random.randint(-10, 10),
                        random.randint(-10, 10),
                        duration=random.uniform(0.5, 1.3)
                    )
        except Exception as e:
            print(f"鼠标移动失败: {str(e)}")     
    def shoot_to_json_result(self):
        screenshot=pyautogui.screenshot()
        timstamp=time.time()
        dirpath=os.path.join(os.getcwd(),'screenshot')
        os.makedirs(dirpath,exist_ok=True)
        fielpath=os.path.join(dirpath,f'{str(timstamp).replace('.','')}.PNG')
        screenshot.save(fielpath, format="PNG")
        json_result=get_baidu3_location_json(fielpath)
        return json_result
    
    def set_window_position(self, exename, destx, desty, width=1016, height=1006):
        try:
            def callback(hwnd, _):
                try:
                    _, pid = win32process.GetWindowThreadProcessId(hwnd)
                    process = psutil.Process(pid)
                    if exename.lower() in process.name().lower():
                        # 恢复最小化窗口
                        if win32gui.IsIconic(hwnd):
                            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
                        # # 激活窗口到前台
                        win32gui.SetForegroundWindow(hwnd)
                        win32gui.MoveWindow(hwnd, destx, desty, width, height, True)
                except (psutil.NoSuchProcess, psutil.AccessDenied, PermissionError):
                    return
                except Exception as e:
                    print(f"进程处理异常: {str(e)}")
                    return
            # 枚举所有窗口
            win32gui.EnumWindows(callback, None)
            return True
        except Exception as e:
            print(f"窗口移动失败: {e}")
            return False
    def close_windows_by_processname(self,processname):
        """关闭所有ziniaobrowser.exe进程的窗口"""
        try:
            def callback(hwnd, _):
                try:
                    # 获取窗口的进程ID
                    _, pid = win32process.GetWindowThreadProcessId(hwnd)
                    # 获取进程对象
                    process = psutil.Process(pid)
                    # 检查进程名称是否包含目标字符串
                    if  processname.lower() in process.name().lower():
                        # 发送关闭消息
                        win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
                except (psutil.NoSuchProcess, psutil.AccessDenied, PermissionError):
                    return
                except Exception as e:
                    print(f"窗口关闭异常: {str(e)}")
                    return
                    
            # 枚举所有窗口
            win32gui.EnumWindows(callback, None)
            return True
        except Exception as e:
            print(f"窗口关闭失败: {e}")
            return False
    def closeEvent(self, event):
        """窗口关闭时停止线程"""
        
        event.accept()
    def get_sequence(self):
        newseq=''       
        
        if self.seqindex>=100 or not self.seqs:
            self.seqindex=0
            self.seqs=self.dbhelper.get_next_sequence()

        if self.seqs and self.seqindex<100:
            newseq= self.seqs[self.seqindex]

        self.seqindex+=1 
        return newseq   
    def get_window_info(self, exename):
        """获取指定进程窗口的位置和尺寸信息"""
        def callback(hwnd, results):
            try:
                _, pid = win32process.GetWindowThreadProcessId(hwnd)
                process = psutil.Process(pid)
                if exename.lower() in process.name().lower():
                    rect = win32gui.GetWindowRect(hwnd)
                    left, top, right, bottom = rect
                    results.append((
                        left, 
                        top, 
                        right - left,  # width
                        bottom - top   # height
                    ))
            except (psutil.NoSuchProcess, psutil.AccessDenied, PermissionError):
                return
            except Exception as e:
                print(f"窗口信息获取异常: {str(e)}")
                return

        results = []
        win32gui.EnumWindows(callback, results)
        return results[0] if results else None  
    def process_text_input(self, tax_image_path, input_text,addtionalwidth=14, addtionalheight=56):
        # 步骤1：定位tax标签
        tax_center = self.get_location_by_image(tax_image_path)
        if not tax_center:
            print("未找到tax标签")
            return False

        # 步骤2：计算文本框坐标（tax标签下方56像素）
        textfield_x = tax_center[0] + random.randint(10, addtionalwidth*2)  # 横向随机偏移
        textfield_y = tax_center[1] + 56 + random.randint(30, addtionalheight)  # 纵向偏移+随机
        
        # 步骤3：模拟人工点击输入
        try:
            # 移动并点击文本框
            self.human_like_move_and_click(textfield_x, textfield_y)
            
            # 清空现有内容
            pyautogui.hotkey('ctrl', 'a')
            time.sleep(0.2)
            pyautogui.press('backspace')
            
            # 输入内容（带随机间隔）
            for char in input_text:
                pyautogui.write(char, interval=random.uniform(0.05, 0.15))
                if random.random() < 0.1:  # 10%概率输入错误并修正
                    pyautogui.press('backspace')
                    pyautogui.write(char)
            
            # 验证输入
            pyautogui.hotkey('ctrl', 'a')
            pyautogui.hotkey('ctrl', 'c')
            time.sleep(0.3)
            clipboard_text = pyperclip.paste()
            
            if clipboard_text == input_text:
                print("输入验证成功")
                return True
            else:
                print("输入验证失败，尝试重新输入")
                return self.process_tax_input(tax_image_path, input_text)  # 递归重试
        except Exception as e:
            print(f"输入过程中发生错误: {str(e)}")
            return False

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    # window.get_sequence()
    sys.exit(app.exec_())

